package com.example.learn_gl_android.anglib.util.math

data class Vector4(val elements: FloatArray = FloatArray(4)) : Cloneable{

    companion object {
        fun one() : Vector4 {
            val ret = Vector4()
            ret.elements[0] = 1f
            ret.elements[1] = 1f
            ret.elements[2] = 1f
            ret.elements[3] = 1f

            return ret
        }

        fun cross(v1: Vector4, v2 : Vector4, v3:Vector4) : Vector4{
            val ret = Vector4()

            val u = v1.elements
            val v = v2.elements
            val w = v3.elements

            val A = v[0] * w[1] - v[1] * w[0]
            val B = v[0] * w[2] - v[2] * w[0]
            val C = v[0] * w[3] - v[3] * w[0]
            val D = v[1] * w[2] - v[2] * w[1]
            val E = v[1] * w[3] - v[3] * w[1]
            val F = v[2] * w[3] - v[3] * w[2]
            val G = u[0];
            val H = u[1];
            val I = u[2];
            val J = u[3];

            ret.elements[0] = H * F - I * E + J * D;
            ret.elements[1] = -(G * F) + I * C - J * B;
            ret.elements[2] = G * E - H * C + J * A;
            ret.elements[3] = -(G * D) + H * B - I * A;

            return ret;
        }

        fun dot(v1: Vector4, v2 : Vector4) : Float{
            val a = v1.elements
            val b = v2.elements

            return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]
        }
    }

    operator fun plus (other : Vector4) : Vector4{
        val ret = Vector4()
        ret.elements[0] = elements[0] + other.elements[0]
        ret.elements[1] = elements[1] + other.elements[1]
        ret.elements[2] = elements[2] + other.elements[2]
        ret.elements[3] = elements[3] + other.elements[3]
        return ret
    }
    operator fun plusAssign (other : Vector4) {

        elements[0] = elements[0] + other.elements[0]
        elements[1] = elements[1] + other.elements[1]
        elements[2] = elements[2] + other.elements[2]
        elements[3] = elements[3] + other.elements[3]
    }

    operator fun minus (other : Vector4) : Vector4{
        val ret = Vector4()
        ret.elements[0] = elements[0] - other.elements[0]
        ret.elements[1] = elements[1] - other.elements[1]
        ret.elements[2] = elements[2] - other.elements[2]
        ret.elements[3] = elements[3] - other.elements[3]
        return ret
    }

    operator fun minusAssign (other : Vector4) {
        elements[0] = elements[0] - other.elements[0]
        elements[1] = elements[1] - other.elements[1]
        elements[2] = elements[2] - other.elements[2]
        elements[3] = elements[3] - other.elements[3]
    }


    override fun clone(): Vector4 {
        return Vector4(elements.clone())
    }

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false

        other as Vector4

        return elements.contentEquals(other.elements)
    }

    override fun hashCode(): Int {
        return elements.contentHashCode()
    }

}